/**
 * User: Taivo
 * Date: 14.03.12
 * Time: 12:42
 */
function Bomb(id, x_abs, y_abs, planter) {
    this.setID(id);
    this.setPos(x_abs, y_abs);
    // constants which can be modified manually
    this.delay = 42; // time in FPS it takes the bomb to explode
    this.animationDuration = 23;
    this.radius = 2; // explosion default reach
    this.imagesPerGrid = 1; // defines how many images to create per grid when exploding
    this.bombIncreaseTime = 17;
    // end

    this.planter = planter; // player, who planted the bomb
    this.timer = 0; // this is used to calculate explosion delay

    this.leftReach = this.radius;
    this.upperReach = this.radius;
    this.rightReach = this.radius;
    this.lowerReach = this.radius;

    this.explosionTimer = 0;
}

Bomb.inherits(GameObject2);

Bomb.method('explode', function () {
    this.planter.bombExploded();
    // removes bomb
    OurGame.bombs[OurGame.bombs.indexOf(this)] = undefined;
    // explodes walls
    var toExplode = [];
    var pos;
    if (isExplodable(pos = this.getShiftedleftReachPos())) {
        toExplode.push(pos);
    }
    if (isExplodable(pos = this.getShiftedUpPos())) {
        toExplode.push(pos);
    }
    if (isExplodable(pos = this.getShiftedrightReachPos())) {
        toExplode.push(pos);
    }
    if (isExplodable(pos = this.getShiftedDownPos())) {
        toExplode.push(pos);
    }
    explodeBlocks(toExplode);
    if (level.map[Math.floor(this.x / OurGame.grid)][Math.floor(this.y / OurGame.grid)].charAt(0) != "p") {
        level.map[Math.floor(this.x / OurGame.grid)][Math.floor(this.y / OurGame.grid)] = "f0";

    }
});

Bomb.method('removeLives', function () {
    for (var i = 0; i < OurGame.players.length; i++) {
        if (this.isPosInBombReach(OurGame.players[i].getPosX(), OurGame.players[i].getPosY())) {
            if (OurGame.players[i].removeLife() && this.planter !== OurGame.players[i]) {
                this.planter.addKills();
            }
        }
    }
});

Bomb.method('getNearbyBombs', function () {
    var nearbyBombs = [];
    var pos = this.getShiftedleftReachPos();
    var foundBomb = getItemByPos(OurGame.bombs, pos.x, pos.y);
    if (foundBomb != -1 && foundBomb != this) {
        nearbyBombs.push(foundBomb);
    }
    pos = this.getShiftedUpPos();
    foundBomb = getItemByPos(OurGame.bombs, pos.x, pos.y);
    if (foundBomb != -1 && foundBomb != this) {
        nearbyBombs.push(foundBomb);
    }
    pos = this.getShiftedrightReachPos();
    foundBomb = getItemByPos(OurGame.bombs, pos.x, pos.y);
    if (foundBomb != -1 && foundBomb != this) {
        nearbyBombs.push(foundBomb);
    }
    pos = this.getShiftedDownPos();
    foundBomb = getItemByPos(OurGame.bombs, pos.x, pos.y);
    if (foundBomb != -1 && foundBomb != this) {
        nearbyBombs.push(foundBomb);
    }
    return nearbyBombs;
});
Bomb.method('changeReaches', function () {
    var x = this.getPosX();
    var y = this.getPosY();
    for (var l = 1; l <= this.leftReach; l++) {
        if (x - l < 0) {
            this.leftReach = l - 1;
            break;
        }
        else if (!isPlaceFree(x - l, y)) {
            this.leftReach = l;
            break;
        }
    }
    for (var u = 1; u <= this.upperReach; u++) {
        if (y - u < 0) {
            this.upperReach = u - 1;
            break;
        }
        else if (!isPlaceFree(x, y - u)) {
            this.upperReach = u;
            break;
        }
    }
    var max = level.map.length;
    for (var r = 1; r <= this.rightReach; r++) {
        if (x + r >= max) {
            this.rightReach = r - 1;
            break;
        }
        else if (!isPlaceFree(x + r, y)) {
            this.rightReach = r;
            break;
        }
    }
    max = level.map[0].length;
    for (var d = 1; d <= this.lowerReach; d++) {
        if (y + d >= max) {
            this.lowerReach = d - 1;
            break;
        }
        else if (!isPlaceFree(x, y + d)) {
            this.lowerReach = d;
            break;
        }
    }
});
Bomb.method('isPosInBombReach', function (x, y) {
    var bombX = this.getPosX();
    var bombY = this.getPosY();
    if (bombX - this.leftReach <= x && bombY == y && bombX + this.rightReach >= x) {
        return true;
    }
    else if (bombY - this.upperReach <= y && bombX == x && bombY + this.lowerReach >= y) {
        return true;
    }
    else if (bombX == x && bombY == y) {
        return true;
    }
    return false;
});
Bomb.method('explosionAnimation', function () {
    this.changeReaches();
    this.explosionTimer++;

    var nearbyBombs = this.getNearbyBombs();
    for (var i = 0; i < nearbyBombs.length; i++) {
        nearbyBombs[i].timer = this.timer;
        nearbyBombs[i].delay = this.delay;
        nearbyBombs[i].explosionTimer = this.explosionTimer - 0.5; // i have no idea why -0.5 did the job, but now walls are exploded when fireball reaches them
    }

    var increaseImagesCount;
    var timePerImage;
    var explosionImagesCount;
    var timerLeft;
    var explosionMoveSize;
    if (this.explosionTimer < this.bombIncreaseTime) {
        increaseImagesCount = 4;
        timePerImage = Math.floor(this.explosionTimer / increaseImagesCount);
        this.drawExplosion(OurGame.maxGrid * timePerImage, OurGame.maxGrid * 2, OurGame.maxGrid, this.x - OurGame.offSet, this.y - OurGame.offSet, OurGame.maxGrid);
    }
    else {
        explosionImagesCount = 6;
        timerLeft = this.explosionTimer - this.bombIncreaseTime;
        timePerImage = Math.round((explosionImagesCount - 1) * timerLeft / (this.animationDuration - this.bombIncreaseTime));
        this.removeLives();
        for (var j = 1; j <= this.radius * this.imagesPerGrid; j++) {
            explosionMoveSize = Math.round(OurGame.grid * j * timerLeft / (this.animationDuration - this.bombIncreaseTime) / this.imagesPerGrid);
            if (j <= this.leftReach * this.imagesPerGrid) {
                this.drawExplosion(OurGame.maxGrid * timePerImage, OurGame.maxGrid * 3, OurGame.maxGrid, this.x - OurGame.offSet - explosionMoveSize, this.y - OurGame.offSet, OurGame.maxGrid);
            }
            if (j <= this.upperReach * this.imagesPerGrid) {
                this.drawExplosion(OurGame.maxGrid * timePerImage, OurGame.maxGrid * 3, OurGame.maxGrid, this.x - OurGame.offSet, this.y - OurGame.offSet - explosionMoveSize, OurGame.maxGrid);
            }
            if (j <= this.rightReach * this.imagesPerGrid) {
                this.drawExplosion(OurGame.maxGrid * timePerImage, OurGame.maxGrid * 3, OurGame.maxGrid, this.x - OurGame.offSet + explosionMoveSize, this.y - OurGame.offSet, OurGame.maxGrid);
            }
            if (j <= this.lowerReach * this.imagesPerGrid) {
                this.drawExplosion(OurGame.maxGrid * timePerImage, OurGame.maxGrid * 3, OurGame.maxGrid, this.x - OurGame.offSet, this.y - OurGame.offSet + explosionMoveSize, OurGame.maxGrid);
            }
        }
    }
});

Bomb.method('drawExplosion', function (xsrc, ysrc, cutSize, x, y, scaledSize) {
    try {
        OurGame.ctx.drawImage(OurGame.images["spritesheet1"], xsrc, ysrc, cutSize, cutSize, x, y, scaledSize, scaledSize);
    } catch (e) {
        alert(e);
    }
});

Bomb.method('draw', function () {
    try {
        if (this.timer < this.delay - this.animationDuration) {
            OurGame.ctx.drawImage(OurGame.images["spritesheet1"], 0, OurGame.maxGrid * 2, OurGame.maxGrid, OurGame.maxGrid, this.x - OurGame.offSet, this.y - OurGame.offSet, OurGame.maxGrid, OurGame.maxGrid);
        }

    } catch (e) {
        alert(e);
    }
});

Bomb.method('drawExplosionExt', function () {
    try {
        if (this.timer >= this.delay - this.animationDuration) {
            this.explosionAnimation();
        }
    } catch (e) {
        alert(e);
    }
});

Bomb.method('update', function () {
    this.timer++;
    if (this.timer >= this.delay) {
        this.explode();
    }
});
Bomb.method('getShiftedUpPos', function () {
    return {
        x:this.getPosX(),
        y:this.getPosY() - this.upperReach
    };
});
Bomb.method('getShiftedDownPos', function () {
    return {
        x:this.getPosX(),
        y:this.getPosY() + this.lowerReach
    };
});
Bomb.method('getShiftedrightReachPos', function () {
    return {
        x:this.getPosX() + this.rightReach,
        y:this.getPosY()
    };
});
Bomb.method('getShiftedleftReachPos', function () {
    return {
        x:this.getPosX() - this.leftReach,
        y:this.getPosY()
    };
});